#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#define BAUDRATE 9600
#define BAUD_PRESCALER (((F_CPU/(BAUDRATE*16UL))) - 1 )
//Operating Mode: Asynchronous Normal mode for the UBRRn value

void USART_INIT(void)
//This function will set the micro controller for serial communication with the PC
//It sets the necessary baud rate registers, and prescaler value.
{
	UBRR0H = (uint8_t)(BAUD_PRESCALER >> 8);
	UBRR0L = (uint8_t)(BAUD_PRESCALER);
	UCSR0B = (1 << RXEN0) | (1 << TXEN0);
	UCSR0C = (3 << UCSZ00);
}

void USART_SEND(unsigned char data)
//This function sends a character from the ATmega328P to the terminal on the PC.
{
	while(!(UCSR0A & (1 << UDRE0)));
	UDR0 = data;
}

uint16_t ReadADC(uint8_t ADCchannel)
// This function reads and returns the ADC value from a specified input pin
{
	ADMUX = (ADMUX & 0xF0) | (ADCchannel & 0x0F);	// select ADC channel with safety mask
	ADCSRA |= (1<<ADSC);							// single conversion mode
	while( ADCSRA & (1<<ADSC) );					// wait until ADC conversion is complete
	return ADC;
}

int main(void)
{
	ADMUX |= (1<<REFS0);						// select Vref=AVcc
	ADCSRA |= (1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);	// set prescaler to 8 and enable ADC
	USART_INIT();								// Call the USART initialization code

	while(1)
	{
		int temp = ReadADC(0)*5 - 150; //Read ADC value, LM34 conversion: 10mV/1 degree Fahrenheit.
		// temperature = (ADC*5000mV)/1024 = 5*ADC
		unsigned char ones;			//variable to keep the ones place
		unsigned char tens;			//variable to keep the tens place.
		unsigned char tenths;		//variable to keep the tenths place
		tens = (temp/100)%10 + 48;	//calculation of the tens place
		ones = (temp/10)%10 + 50;	//calculation of the ones place, +2 for precision
		tenths = temp%10 + 48;		//calculation of the tenths place
		if (ones==58)		//have to fix when it goes out of range
		{
			ones = 48;
			tens = tens+1;	//adjust tens place
		}
		if (ones==59)		//have to fix when it goes out of range
		{
			 ones = 49; 
			 tens = tens+1;	//adjust tens place
		}
		USART_SEND(tens);	//send tens place digit as a character
		USART_SEND(ones);	//send ones place digit as a character
		USART_SEND(46);		//send a decimal point: "."
		USART_SEND(tenths);	//send tenths place digit as a character
		USART_SEND('\n');	//send a newline
		_delay_ms(1000);
	}
	return 0;
}